﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace PatternSearch
{
    class Program
    {

        static void Main(string[] args)
        {
            var currentDir = Directory.GetCurrentDirectory();
            string corpusPath = currentDir + @"\corpus";
            string patternsFile = currentDir + @"\patterns.txt";
            string outputPath = currentDir + @"\output";

            if (args.Count() == 3)
            {
                corpusPath = args[0];
                patternsFile = args[1];
                outputPath = args[2];
            }

            var info = new DirectoryInfo(corpusPath);
            var files = info.GetFiles("*.xml");

            if (!Directory.Exists(outputPath))
                Directory.CreateDirectory(outputPath);

            Pattern[] patterns = PatternWorker.LoadPatterns(patternsFile);
            Console.WriteLine("Patterns loaded...");

            foreach (var file in files)
            {
                var stream = file.OpenRead();
                string outputFile = "res_" + file.Name;
                var corpus = Corpus.LoadXML(stream, true);
                Console.WriteLine("Corpus loaded...");                

                var output = SearchCourpus(corpus, patterns);
                SaveToFile(outputPath + "\\" + outputFile + ".txt", output);
            }

            
        }

        static Dictionary<int, List<string>> SearchCourpus(List<Word> corpus, Pattern[] patterns)
        {
            ProgressCounter progres = new ProgressCounter(corpus.Count, "Searching corpus...");
            var output = new Dictionary<int, List<string>>();
            for (int i = 0; i < corpus.Count; i++)
            {
                Word word = corpus[i];
                progres.Increment();
                foreach (Pattern pattern in patterns)
                {
                    if (pattern.Root.ConformsTo(word))
                    {
                        string phrase = pattern.TryGetConstruction(word, i, corpus);
                        if (phrase != null)
                        {
                            if (!output.ContainsKey(pattern.ID))
                                output.Add(pattern.ID, new List<string>());
                            output[pattern.ID].Add(phrase);
                        }
                    }
                }
            }
            return output;
        }

        static void SaveToFile(string fileName, Dictionary<int, List<string>> output)
        {
            List<int> patternIDs = output.Keys.ToList();
            patternIDs.Sort();
            StreamWriter writer = new StreamWriter(fileName, false, Encoding.UTF8);
            foreach (var id in patternIDs)
            {

                foreach (var phrase in output[id])
                {
                    writer.WriteLine(id + ":\t" + phrase);
                    writer.Flush();
                }
            }
            Console.WriteLine("Results saved!");
        }

    }

    class ProgressCounter
    {
        int count = 0;
        int percent = 0;
        int progress = 0;
        string message = String.Empty;

        public ProgressCounter(int capacity, string message)
        {
            percent = capacity / 100 + 1;
            this.message = message;
        }

        public void Increment()
        {
            count++;
            if (count > percent)
            {
                count = 0;
                progress++;
                Console.Clear();
                Console.WriteLine(message);
                Console.WriteLine(progress + "%\t complete...");
            }
        }

    }

}
